import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:dio/dio.dart' as dio;
import '../services/dio_service.dart';
import '../models/index.dart';
import '../models/project/project_rule_model.dart';
import '../models/request/expert_bid_req.dart';
import '../models/project/expert_bid_result.dart';

/// 项目API调用类
/// 
/// 负责所有项目相关的API调用
/// 使用DioService进行网络请求，返回标准化的ApiResponse
/// 这是一个工具类，不是服务类
class ProjectApi {
  // 🔗 API路径常量
  static const String projectListPath = '/v1/app/projectList';
  static const String projectInfoPath = '/v1/app/projectInfo';
  static const String projectExpertListPath = '/v1/app/projectExpertList';
  static const String projectSupplierListPath = '/v1/app/projectSupplierList';
  static const String projectReviewRulePath = '/v1/app/projectReviewRule';
  static const String projectStepInfoPath = '/v1/app/projectStepInfo';
  static const String projectFilesPath = '/v1/app/getProjectFiles';
  static const String uploadSignaturePath = '/v1/app/uploadImg';
  static const String expertBidPath = '/v1/app/expertBid';
  
  // 📡 网络服务实例
  static DioService get _dioService => Get.find<DioService>();
  
  /// 获取项目列表API
  /// 
  /// [expertId] 专家ID
  /// [flag] 项目标志位：0-作为评审人的项目列表，1-作为验收人的项目列表，2-作为评标人的项目列表
  /// 使用DioService自动携带的token进行请求
  /// 直接返回项目列表 List<ProjectModel>
  static Future<List<ProjectModel>> getProjectList({
    required int expertId,
    required int flag,
  }) async {
    try {
      debugPrint('📋 开始获取项目列表');
      debugPrint('📋 专家ID: $expertId, 标志位: $flag');
      
      // 构建查询参数
      final queryParams = {
        'expertId': expertId.toString(),
        'flag': flag.toString(),
      };
      
      debugPrint('📋 发送GET请求到: $projectListPath');
      debugPrint('📋 查询参数: $queryParams');
      
      // 使用DioService发送GET请求，token会被自动添加到请求头
      final response = await _dioService.get(
        projectListPath,
        queryParameters: queryParams,
      );
      
      debugPrint('📋 项目列表请求完成，状态码: ${response.statusCode}');
      
      // 解析响应数据
      if (response.data != null && response.data is Map<String, dynamic>) {
        final responseData = response.data as Map<String, dynamic>;
        
        debugPrint('📋 项目列表响应数据类型: ${responseData.runtimeType}');
        
        // 检查响应状态码
        final code = responseData['code']?.toInt() ?? -1;
        final msg = responseData['message']?.toString() ?? responseData['msg']?.toString();
        
        if (code == 0) { // 项目列表API成功时code为0
          // 成功响应 - 解析data字段为List<ProjectModel>
          final data = responseData['data'];
          if (data != null && data is List) {
            final projectList = data
                .map((item) {
                  if (item is Map<String, dynamic>) {
                    return ProjectModel.fromJson(item);
                  } else {
                    debugPrint('⚠️ 跳过无效的项目数据: $item');
                    return null;
                  }
                })
                .where((project) => project != null)
                .cast<ProjectModel>()
                .toList();
            
            debugPrint('✅ 获取项目列表成功，共 ${projectList.length} 个项目');
            
            return projectList;
          } else if (data == null) {
            // 如果data为null，返回空列表
            debugPrint('📋 项目列表为空');
            return <ProjectModel>[];
          } else {
            debugPrint('❌ 项目列表数据格式错误: ${data.runtimeType}');
            throw Exception('项目列表数据格式错误');
          }
        } else {
          // 业务失败响应
          debugPrint('❌ 获取项目列表失败: $msg');
          throw Exception(msg ?? '获取项目列表失败');
        }
      } else {
        debugPrint('❌ 服务器响应格式错误');
        throw Exception('服务器响应格式错误');
      }
    } catch (e) {
      debugPrint('❌ 获取项目列表异常: $e');
      rethrow;
    }
  }

  /// 获取项目详细信息API
  /// 
  /// [projectId] 项目ID
  /// 使用DioService自动携带的token进行请求
  /// 直接返回项目详细信息 ProjectModel
  static Future<ProjectModel> getProjectInfo({
    required int projectId,
  }) async {
    try {
      debugPrint('📋 开始获取项目详细信息');
      debugPrint('📋 项目ID: $projectId');
      
      // 构建查询参数
      final queryParams = {
        'projectId': projectId.toString(),
      };
      
      debugPrint('📋 发送GET请求到: $projectInfoPath');
      debugPrint('📋 查询参数: $queryParams');
      
      // 使用DioService发送GET请求，token会被自动添加到请求头
      final response = await _dioService.get(
        projectInfoPath,
        queryParameters: queryParams,
      );
      
      debugPrint('📋 项目详细信息请求完成，状态码: ${response.statusCode}');
      
      // 解析响应数据
      if (response.data != null && response.data is Map<String, dynamic>) {
        final responseData = response.data as Map<String, dynamic>;
        
        debugPrint('📋 项目详细信息响应数据类型: ${responseData.runtimeType}');
        
        // 检查响应状态码
        final code = responseData['code']?.toInt() ?? -1;
        final msg = responseData['message']?.toString() ?? responseData['msg']?.toString();
        
        if (code == 0) { // 项目详细信息API成功时code为0
          // 成功响应 - 解析data字段为ProjectModel
          final data = responseData['data'];
          if (data != null && data is Map<String, dynamic>) {
            final project = ProjectModel.fromJson(data);
            
            debugPrint('✅ 获取项目详细信息成功: ${project.projectName}');
            
            return project;
          } else {
            debugPrint('❌ 项目详细信息数据格式错误: ${data.runtimeType}');
            throw Exception('项目详细信息数据格式错误');
          }
        } else {
          // 业务失败响应
          debugPrint('❌ 获取项目详细信息失败: $msg');
          throw Exception(msg ?? '获取项目详细信息失败');
        }
      } else {
        debugPrint('❌ 服务器响应格式错误');
        throw Exception('服务器响应格式错误');
      }
    } catch (e) {
      debugPrint('❌ 获取项目详细信息异常: $e');
      rethrow;
    }
  }

  /// 获取项目专家列表API
  /// 
  /// [projectId] 项目ID
  /// [flag] 项目标志位：0-作为评审人的专家列表，1-作为验收人的专家列表，2-作为评标人的专家列表
  /// 使用DioService自动携带的token进行请求
  /// 直接返回专家列表 List<ProjectExpert>
  static Future<List<ProjectExpert>> getProjectExpertList({
    required int projectId,
    required int flag,
  }) async {
    try {
      debugPrint('👥 开始获取项目专家列表');
      debugPrint('👥 项目ID: $projectId, 标志位: $flag');
      
      // 构建查询参数
      final queryParams = {
        'projectId': projectId.toString(),
        'flag': flag.toString(),
      };
      
      debugPrint('👥 发送GET请求到: $projectExpertListPath');
      debugPrint('👥 查询参数: $queryParams');
      
      // 使用DioService发送GET请求，token会被自动添加到请求头
      final response = await _dioService.get(
        projectExpertListPath,
        queryParameters: queryParams,
      );
      
      debugPrint('👥 项目专家列表请求完成，状态码: ${response.statusCode}');
      
      // 解析响应数据
      if (response.data != null && response.data is Map<String, dynamic>) {
        final responseData = response.data as Map<String, dynamic>;
        
        debugPrint('👥 项目专家列表响应数据类型: ${responseData.runtimeType}');
        
        // 检查响应状态码
        final code = responseData['code']?.toInt() ?? -1;
        final msg = responseData['message']?.toString() ?? responseData['msg']?.toString();
        
        if (code == 0) { // 项目专家列表API成功时code为0
          // 成功响应 - 解析data字段为List<ProjectExpert>
          final data = responseData['data'];
          if (data != null && data is List) {
            final expertList = data
                .map((item) {
                  if (item is Map<String, dynamic>) {
                    return ProjectExpert.fromJson(item);
                  } else {
                    debugPrint('⚠️ 跳过无效的专家数据: $item');
                    return null;
                  }
                })
                .where((expert) => expert != null)
                .cast<ProjectExpert>()
                .toList();
            
            debugPrint('✅ 获取项目专家列表成功，共 ${expertList.length} 个专家');
            
            // 打印专家信息摘要（仅在debug模式下）
            if (expertList.isNotEmpty) {
              for (final expert in expertList) {
                debugPrint('👤 专家: ${expert.expertName} (${expert.corpName}) - ${expert.officialCapacity}');
              }
            }
            
            return expertList;
          } else if (data == null) {
            // 如果data为null，返回空列表
            debugPrint('👥 项目专家列表为空');
            return <ProjectExpert>[];
          } else {
            debugPrint('❌ 项目专家列表数据格式错误: ${data.runtimeType}');
            throw Exception('项目专家列表数据格式错误');
          }
        } else {
          // 业务失败响应
          debugPrint('❌ 获取项目专家列表失败: $msg');
          throw Exception(msg ?? '获取项目专家列表失败');
        }
      } else {
        debugPrint('❌ 服务器响应格式错误');
        throw Exception('服务器响应格式错误');
      }
    } catch (e) {
      debugPrint('❌ 获取项目专家列表异常: $e');
      rethrow;
    }
  }

  /// 获取项目供应商列表API
  /// 
  /// [projectId] 项目ID
  /// [expertId] 专家ID
  /// 使用DioService自动携带的token进行请求
  /// 直接返回供应商列表 List<ProjectSupplier>
  static Future<List<ProjectSupplier>> getProjectSupplierList({
    required int projectId,
    required int expertId,
  }) async {
    try {
      debugPrint('🏢 开始获取项目供应商列表');
      debugPrint('🏢 项目ID: $projectId, 专家ID: $expertId');
      
      // 构建查询参数
      final queryParams = {
        'projectId': projectId.toString(),
        'expertId': expertId.toString(),
      };
      
      debugPrint('🏢 发送GET请求到: $projectSupplierListPath');
      debugPrint('🏢 查询参数: $queryParams');
      
      // 使用DioService发送GET请求，token会被自动添加到请求头
      final response = await _dioService.get(
        projectSupplierListPath,
        queryParameters: queryParams,
      );
      
      debugPrint('🏢 项目供应商列表请求完成，状态码: ${response.statusCode}');
      
      // 解析响应数据
      if (response.data != null && response.data is Map<String, dynamic>) {
        final responseData = response.data as Map<String, dynamic>;
        
        debugPrint('🏢 项目供应商列表响应数据类型: ${responseData.runtimeType}');
        
        // 检查响应状态码
        final code = responseData['code']?.toInt() ?? -1;
        final msg = responseData['message']?.toString() ?? responseData['msg']?.toString();
        
        if (code == 0) { // 项目供应商列表API成功时code为0
          // 成功响应 - 解析data字段为List<ProjectSupplier>
          final data = responseData['data'];
          if (data != null && data is List) {
            final supplierList = data
                .map((item) {
                  if (item is Map<String, dynamic>) {
                    return ProjectSupplier.fromJson(item);
                  } else {
                    debugPrint('⚠️ 跳过无效的供应商数据: $item');
                    return null;
                  }
                })
                .where((supplier) => supplier != null)
                .cast<ProjectSupplier>()
                .toList();
            
            debugPrint('✅ 获取项目供应商列表成功，共 ${supplierList.length} 个供应商');
            
            // 打印供应商信息摘要（仅在debug模式下）
            if (supplierList.isNotEmpty) {
              for (final supplier in supplierList) {
                debugPrint('🏢 供应商: ${supplier.corpName} (${supplier.legalPerson}) - 投标状态: ${supplier.bidFlag == 1 ? "已投标" : "未投标"}');
              }
            }
            
            return supplierList;
          } else if (data == null) {
            // 如果data为null，返回空列表
            debugPrint('🏢 项目供应商列表为空');
            return <ProjectSupplier>[];
          } else {
            debugPrint('❌ 项目供应商列表数据格式错误: ${data.runtimeType}');
            throw Exception('项目供应商列表数据格式错误');
          }
        } else {
          // 业务失败响应
          debugPrint('❌ 获取项目供应商列表失败: $msg');
          throw Exception(msg ?? '获取项目供应商列表失败');
        }
      } else {
        debugPrint('❌ 服务器响应格式错误');
        throw Exception('服务器响应格式错误');
      }
    } catch (e) {
      debugPrint('❌ 获取项目供应商列表异常: $e');
      rethrow;
    }
  }

  /// 获取项目资格评审和评分规则信息API
  /// 
  /// [projectId] 项目ID
  /// 使用DioService自动携带的token进行请求
  /// 直接返回项目规则信息 ProjectRuleModel
  static Future<ProjectRuleModel> getProjectReviewRule({
    required int projectId,
  }) async {
    try {
      debugPrint('📋 开始获取项目评审规则');
      debugPrint('📋 项目ID: $projectId');
      
      // 构建查询参数
      final queryParams = {
        'projectId': projectId.toString(),
      };
      
      debugPrint('📋 发送GET请求到: $projectReviewRulePath');
      debugPrint('📋 查询参数: $queryParams');
      
      // 使用DioService发送GET请求，token会被自动添加到请求头
      final response = await _dioService.get(
        projectReviewRulePath,
        queryParameters: queryParams,
      );
      
      debugPrint('📋 项目评审规则请求完成，状态码: ${response.statusCode}');
      
      // 解析响应数据
      if (response.data != null && response.data is Map<String, dynamic>) {
        final responseData = response.data as Map<String, dynamic>;
        
        debugPrint('📋 项目评审规则响应数据类型: ${responseData.runtimeType}');
        
        // 检查响应状态码
        final code = responseData['code']?.toInt() ?? -1;
        final msg = responseData['message']?.toString() ?? responseData['msg']?.toString();
        
        if (code == 0) { // 项目评审规则API成功时code为0
          // 成功响应 - 解析data字段为ProjectRuleModel
          final data = responseData['data'];
          if (data != null && data is Map<String, dynamic>) {
            final projectRule = ProjectRuleModel.fromJson(data);
            
            debugPrint('✅ 获取项目评审规则成功');
            debugPrint('📋 评分规则长度: ${projectRule.scoreRule?.length ?? 0}');
            debugPrint('📋 资格评审规则长度: ${projectRule.reviewRule?.length ?? 0}');
            
            // 在debug模式下打印规则概要
            if (projectRule.scoreRule != null && projectRule.scoreRule!.isNotEmpty) {
              try {
                // 尝试解析scoreRule JSON来获取概要信息
                debugPrint('📋 评分规则包含评分标准配置');
              } catch (e) {
                debugPrint('⚠️ 评分规则JSON解析预览失败: $e');
              }
            }
            
            if (projectRule.reviewRule != null && projectRule.reviewRule!.isNotEmpty) {
              debugPrint('📋 资格评审规则包含HTML表格数据');
            }
            
            return projectRule;
          } else {
            debugPrint('❌ 项目评审规则数据格式错误: ${data.runtimeType}');
            throw Exception('项目评审规则数据格式错误');
          }
        } else {
          // 业务失败响应
          debugPrint('❌ 获取项目评审规则失败: $msg');
          throw Exception(msg ?? '获取项目评审规则失败');
        }
      } else {
        debugPrint('❌ 服务器响应格式错误');
        throw Exception('服务器响应格式错误');
      }
    } catch (e) {
      debugPrint('❌ 获取项目评审规则异常: $e');
      rethrow;
    }
  }

  /// 获取项目步骤信息API
  /// 
  /// [projectId] 项目ID
  /// [step] 步骤参数：2-采购步骤，3-软件步骤，4-实施步骤，5-云服务步骤，6-预算步骤，7-获取全部步骤（2~6）
  /// 使用DioService自动携带的token进行请求
  /// 返回步骤信息 Map<String, dynamic>
  static Future<Map<String, dynamic>> getProjectStepInfo({
    required int projectId,
    required int step,
  }) async {
    try {
      debugPrint('📊 开始获取项目步骤信息');
      debugPrint('📊 项目ID: $projectId, 步骤: $step');
      
      // 构建查询参数
      final queryParams = {
        'projectId': projectId.toString(),
        'step': step.toString(),
      };
      
      debugPrint('📊 发送GET请求到: $projectStepInfoPath');
      debugPrint('📊 查询参数: $queryParams');
      
      // 使用DioService发送GET请求，token会被自动添加到请求头
      final response = await _dioService.get(
        projectStepInfoPath,
        queryParameters: queryParams,
      );
      
      debugPrint('📊 项目步骤信息请求完成，状态码: ${response.statusCode}');
      
      // 解析响应数据
      if (response.data != null && response.data is Map<String, dynamic>) {
        final responseData = response.data as Map<String, dynamic>;
        
        debugPrint('📊 项目步骤信息响应数据类型: ${responseData.runtimeType}');
        debugPrint('📊 响应数据字段: ${responseData.keys}');
        
        // 🔥 特殊处理：该API直接返回数据对象，没有包装在标准的 {code, msg, data} 格式中
        // 如果响应中包含 softwareJson, purchaseJson 等字段，说明是直接返回的数据
        if (responseData.containsKey('softwareJson') || 
            responseData.containsKey('purchaseJson') ||
            responseData.containsKey('implementationJson') ||
            responseData.containsKey('cloudJson') ||
            responseData.containsKey('budgetJson')) {
          debugPrint('✅ 获取项目步骤信息成功（直接返回数据格式）');
          debugPrint('📊 步骤数据字段: ${responseData.keys}');
          
          // 直接返回响应数据，每个字段都是JSON字符串，需要在使用时解析
          return responseData;
        }
        
        // 🔥 特殊处理：如果返回的是 categories + totalAmount 格式（预算数据）
        // 将其包装为 budgetJson 字段
        if (responseData.containsKey('categories') && responseData.containsKey('totalAmount')) {
          debugPrint('✅ 获取项目步骤信息成功（预算数据格式）');
          debugPrint('📊 检测到预算数据，自动包装为 budgetJson');
          
          // 将预算数据转换为JSON字符串并包装
          final budgetJsonString = jsonEncode(responseData);
          return {
            'budgetJson': budgetJsonString,
          };
        }
        
        // 检查是否是标准的响应格式 {code, msg, data}
        final code = responseData['code']?.toInt();
        if (code != null) {
          final msg = responseData['message']?.toString() ?? responseData['msg']?.toString();
          
          if (code == 0) {
            // 成功响应 - 解析data字段
            final data = responseData['data'];
            
            if (data == null) {
              debugPrint('⚠️ 项目步骤信息数据为空');
              return <String, dynamic>{};
            }
            
            // data 是一个 JSON 字符串，需要解析
            if (data is String && data.isNotEmpty) {
              try {
                // 尝试解析 JSON 字符串
                final jsonData = jsonDecode(data);
                if (jsonData is Map<String, dynamic>) {
                  debugPrint('✅ 获取项目步骤信息成功（标准格式）');
                  debugPrint('📊 步骤数据字段: ${jsonData.keys}');
                  return jsonData;
                } else {
                  debugPrint('❌ 项目步骤信息JSON数据格式错误: ${jsonData.runtimeType}');
                  throw Exception('项目步骤信息数据格式错误');
                }
              } catch (e) {
                debugPrint('❌ 项目步骤信息JSON解析失败: $e');
                debugPrint('📊 原始数据: ${data.substring(0, data.length > 200 ? 200 : data.length)}...');
                throw Exception('项目步骤信息数据解析失败');
              }
            } else if (data is Map<String, dynamic>) {
              // 如果已经是 Map，直接返回
              debugPrint('✅ 获取项目步骤信息成功（标准格式，已解析为Map）');
              debugPrint('📊 步骤数据字段: ${data.keys}');
              return data;
            } else {
              debugPrint('❌ 项目步骤信息数据类型错误: ${data.runtimeType}');
              throw Exception('项目步骤信息数据格式错误');
            }
          } else {
            // 业务失败响应
            debugPrint('❌ 获取项目步骤信息失败: $msg');
            throw Exception(msg ?? '获取项目步骤信息失败');
          }
        } else {
          // 没有code字段，也没有步骤数据字段，不知道如何处理
          debugPrint('❌ 无法识别的响应格式: ${responseData.keys}');
          throw Exception('服务器响应格式错误');
        }
      } else {
        debugPrint('❌ 服务器响应格式错误');
        throw Exception('服务器响应格式错误');
      }
    } catch (e) {
      debugPrint('❌ 获取项目步骤信息异常: $e');
      rethrow;
    }
  }

  /// 上传签名图片API
  /// 
  /// [expertId] 专家ID
  /// [projectId] 项目ID
  /// [flag] 项目专家类型：0-作为评审人，1-作为验收人，2-作为评标人
  /// [file] 签名图片文件
  /// [reviewStatus] 评审/验收状态：1-未通过，2-通过。只有评审（flag=0）和验收（flag=1）时此参数才有用
  /// [bidSuggestion] 评标的总意见，可以为空。只有评标的时候（flag=2），才传这个字段
  /// [isLeader] 是否是组长提交：0-否，1-是。只有评标的时候（flag=2），才传这个字段
  /// 使用DioService自动携带的token进行请求
  /// 返回上传结果 UploadSignatureResult
  static Future<UploadSignatureResult> uploadSignature({
    required int expertId,
    required int projectId,
    required int flag,
    required File file,
    int? reviewStatus,
    String? bidSuggestion,
    int? isLeader,
  }) async {
    try {
      debugPrint('📷 开始上传签名图片');
      debugPrint('📷 专家ID: $expertId, 项目ID: $projectId, 标志位: $flag');
      if (bidSuggestion != null) {
        debugPrint('📷 评标总意见: $bidSuggestion');
      }
      if (isLeader != null) {
        debugPrint('📷 是否组长: $isLeader');
      }
      
      // 构建查询参数
      final queryParams = <String, String>{
        'expertId': expertId.toString(),
        'projectId': projectId.toString(),
        'flag': flag.toString(),
      };
      
      // 在评审场景（flag=0）或验收场景（flag=1）时添加 reviewStatus 参数
      if (flag == 0 || flag == 1) {
        if (reviewStatus != null) {
          queryParams['reviewStatus'] = reviewStatus.toString();
          debugPrint('📷 添加reviewStatus参数: $reviewStatus (${reviewStatus == 1 ? "未通过" : "通过"})');
        } else {
          debugPrint('⚠️ 警告：flag=$flag时reviewStatus应该必填，但当前为null');
        }
      }
      
      // 只在评标场景（flag=2）时添加 bid_suggestion 和 isLeader 参数
      if (flag == 2) {
        if (bidSuggestion != null && bidSuggestion.isNotEmpty) {
          queryParams['bid_suggestion'] = bidSuggestion;
        }
        if (isLeader != null) {
          queryParams['isLeader'] = isLeader.toString();
        }
      }
      
      debugPrint('📷 发送POST请求到: $uploadSignaturePath');
      debugPrint('📷 查询参数: $queryParams');
      debugPrint('📷 文件路径: ${file.path}');
      
      // 创建FormData
      final formData = dio.FormData.fromMap({
        'file': await dio.MultipartFile.fromFile(
          file.path,
          filename: file.path.split('/').last,
        ),
      });
      
      debugPrint('📷 FormData创建完成');
      
      // 使用DioService发送POST请求，token会被自动添加到请求头
      final response = await _dioService.post(
        uploadSignaturePath,
        data: formData,
        queryParameters: queryParams,
        options: dio.Options(
          contentType: 'multipart/form-data',
        ),
      );
      
      debugPrint('📷 签名图片上传请求完成，状态码: ${response.statusCode}');
      
      // 解析响应数据
      if (response.data != null && response.data is Map<String, dynamic>) {
        final responseData = response.data as Map<String, dynamic>;
        
        debugPrint('📷 签名图片上传响应数据类型: ${responseData.runtimeType}');
        debugPrint('📷 响应数据: $responseData');
        
        // 检查响应状态码（注意：此接口使用error字段而不是code字段）
        final error = responseData['error']?.toInt() ?? 1;
        var url = responseData['url']?.toString() ?? '';
        
        if (error == 0) {
          // 将相对路径转换为完整URL
          // 后端返回的路径可能是：\uploads\20251007\xxx.png
          // 需要转换为：http://10.0.2.2:8081/uploads/20251007/xxx.png
          if (url.isNotEmpty && !url.startsWith('http')) {
            // 替换反斜杠为正斜杠
            url = url.replaceAll('\\', '/');
            // 如果不是以/开头，添加/
            if (!url.startsWith('/')) {
              url = '/$url';
            }
            // 拼接baseUrl
            final baseUrl = _dioService.dio.options.baseUrl;
            url = '$baseUrl$url';
            debugPrint('📷 转换相对路径为完整URL: $url');
          }
          
          debugPrint('✅ 上传签名图片成功: $url');
          
          return UploadSignatureResult(
            success: true,
            url: url,
            errorMessage: null,
          );
        } else {
          // 失败响应
          debugPrint('❌ 上传签名图片失败: error=$error');
          return UploadSignatureResult(
            success: false,
            url: '',
            errorMessage: '上传签名图片失败',
          );
        }
      } else {
        debugPrint('❌ 服务器响应格式错误');
        return UploadSignatureResult(
          success: false,
          url: '',
          errorMessage: '服务器响应格式错误',
        );
      }
    } catch (e) {
      debugPrint('❌ 上传签名图片异常: $e');
      return UploadSignatureResult(
        success: false,
        url: '',
        errorMessage: e.toString(),
      );
    }
  }

  /// 检查当前专家是否是最后一个提交的专家
  /// 
  /// [projectId] 项目ID
  /// [supplierId] 供应商ID，flag=2时，供应商ID>0，否则此字段=0
  /// [flag] 项目标志位：0-作为评审人，1-作为验收人，2-作为评标人
  /// 使用DioService自动携带的token进行请求
  /// 返回 bool 表示是否是最后一个专家
  static Future<bool> checkTheLastExpert({
    required int projectId,
    required int supplierId,
    required int flag,
  }) async {
    try {
      debugPrint('🔍 开始检查是否是最后一个专家');
      debugPrint('🔍 项目ID: $projectId, 供应商ID: $supplierId, 标志位: $flag');
      
      // 构建查询参数
      final queryParams = {
        'projectId': projectId.toString(),
        'supplierId': supplierId.toString(),
        'flag': flag.toString(),
      };
      
      debugPrint('🔍 发送POST请求到: /v1/app/checkTheLastExpert');
      debugPrint('🔍 查询参数: $queryParams');
      
      // 使用DioService发送POST请求，token会被自动添加到请求头
      final response = await _dioService.post(
        '/v1/app/checkTheLastExpert',
        queryParameters: queryParams,
      );
      
      debugPrint('🔍 检查最后专家请求完成，状态码: ${response.statusCode}');
      
      // 解析响应数据
      if (response.data != null && response.data is Map<String, dynamic>) {
        final responseData = response.data as Map<String, dynamic>;
        
        debugPrint('🔍 检查最后专家响应数据类型: ${responseData.runtimeType}');
        debugPrint('🔍 响应数据: $responseData');
        
        // 检查响应状态码
        final code = responseData['code']?.toInt() ?? -1;
        final msg = responseData['msg']?.toString() ?? responseData['message']?.toString();
        
        if (code == 0) {
          // 成功响应 - 解析data字段
          final data = responseData['data'];
          
          // data 可能是 bool 或者其他类型，需要判断
          bool isLastExpert = false;
          
          if (data is bool) {
            isLastExpert = data;
          } else if (data is int) {
            isLastExpert = data == 1; // 1表示是最后一个，0表示不是
          } else if (data is String) {
            isLastExpert = data.toLowerCase() == 'true' || data == '1';
          } else if (data is Map<String, dynamic>) {
            // 如果返回的是对象，可能包含 isLast 字段
            isLastExpert = data['isLast'] == true || data['isLast'] == 1;
          }
          
          debugPrint('✅ 检查最后专家成功: ${isLastExpert ? "是最后一个" : "不是最后一个"}');
          
          return isLastExpert;
        } else {
          // 业务失败响应
          debugPrint('❌ 检查最后专家失败: $msg');
          throw Exception(msg ?? '检查最后专家失败');
        }
      } else {
        debugPrint('❌ 服务器响应格式错误');
        throw Exception('服务器响应格式错误');
      }
    } catch (e) {
      debugPrint('❌ 检查最后专家异常: $e');
      rethrow;
    }
  }

  /// 专家评标API
  /// 
  /// [request] 评标请求参数（包含专家ID、供应商ID、项目ID、评分数据等）
  /// 使用DioService自动携带的token进行请求
  /// 简化版本：提交专家评标（直接使用参数）
  /// 
  /// [expertId] 专家ID
  /// [supplierId] 供应商ID
  /// [projectId] 项目ID
  /// [score] 打分（总分）
  /// [tableHeader] 组装好的打分表格表头（HTML格式）
  /// [tableData] 组装好的打分表格一行数据（HTML格式）
  /// [isLeader] 是否是组长提交：0-否，1-是
  /// 返回 bool 表示是否成功
  static Future<bool> expertBid({
    required int expertId,
    required int supplierId,
    required int projectId,
    required int score,
    required String tableHeader,
    required String tableData,
    int isLeader = 0,
  }) async {
    try {
      debugPrint('🎯 开始提交专家评标（简化版本）');
      
      // 🔥 重要：将数据放在请求体中，避免URL过长导致 "Request header is too large" 错误
      final formData = {
        'expertId': expertId.toString(),
        'supplierId': supplierId.toString(),
        'projectId': projectId.toString(),
        'score': score.toString(),
        'tableHeader': tableHeader,
        'tableData': tableData,
        'isLeader': isLeader.toString(),
      };
      
      debugPrint('🎯 发送POST请求到: $expertBidPath');
      debugPrint('🎯 请求体参数数量: ${formData.length}');
      debugPrint('🎯 tableHeader长度: ${tableHeader.length} 字符');
      debugPrint('🎯 tableData长度: ${tableData.length} 字符');
      
      // 使用DioService发送POST请求，将数据放在请求体中而不是URL参数中
      final response = await _dioService.post(
        expertBidPath,
        data: formData,
        options: dio.Options(
          contentType: 'application/x-www-form-urlencoded',
        ),
      );
      
      debugPrint('🎯 专家评标请求完成，状态码: ${response.statusCode}');
      
      // 解析响应数据
      if (response.data != null && response.data is Map<String, dynamic>) {
        final responseData = response.data as Map<String, dynamic>;
        final code = responseData['code']?.toInt() ?? -1;
        final msg = responseData['msg']?.toString() ?? responseData['message']?.toString();
        
        if (code == 0) {
          debugPrint('✅ 专家评标提交成功');
          return true;
        } else {
          debugPrint('❌ 专家评标提交失败: $msg');
          throw Exception(msg ?? '评标提交失败');
        }
      } else {
        debugPrint('❌ 服务器响应格式错误');
        throw Exception('服务器响应格式错误');
      }
    } catch (e) {
      debugPrint('❌ 专家评标提交异常: $e');
      rethrow;
    }
  }
  
  /// 原版本：提交专家评标（使用请求对象）
  /// 返回评标结果 ExpertBidResult
  static Future<ExpertBidResult> expertBidWithRequest({
    required ExpertBidRequest request,
  }) async {
    try {
      debugPrint('🎯 开始提交专家评标');
      debugPrint('🎯 $request');
      
      // 验证总分是否正确
      if (!request.validateScore()) {
        final calculatedScore = request.tableData.fold<int>(0, (sum, item) => sum + item.score);
        debugPrint('⚠️ 总分验证失败: 传入总分=${request.score}, 计算总分=$calculatedScore');
        return ExpertBidResult.failure(
          errorMessage: '总分不正确，传入总分=${request.score}，实际总分=$calculatedScore',
        );
      }
      
      // 转换为表单数据（使用请求体而不是URL参数，避免 "Request header is too large" 错误）
      final formData = request.toQueryParams();
      
      debugPrint('🎯 发送POST请求到: $expertBidPath');
      debugPrint('🎯 表单数据参数数量: ${formData.length}');
      
      // 使用DioService发送POST请求，将数据放在请求体中而不是URL参数中
      final response = await _dioService.post(
        expertBidPath,
        data: formData,
        options: dio.Options(
          contentType: 'application/x-www-form-urlencoded',
        ),
      );
      
      debugPrint('🎯 专家评标请求完成，状态码: ${response.statusCode}');
      
      // 解析响应数据
      if (response.data != null && response.data is Map<String, dynamic>) {
        final responseData = response.data as Map<String, dynamic>;
        
        debugPrint('🎯 专家评标响应数据类型: ${responseData.runtimeType}');
        debugPrint('🎯 响应数据: $responseData');
        
        // 检查响应状态码
        final code = responseData['code']?.toInt() ?? -1;
        final msg = responseData['msg']?.toString() ?? responseData['message']?.toString();
        
        if (code == 0) {
          // 成功响应
          debugPrint('✅ 专家评标提交成功');
          
          return ExpertBidResult.success(
            message: msg ?? '评标提交成功',
          );
        } else {
          // 业务失败响应
          debugPrint('❌ 专家评标提交失败: $msg');
          return ExpertBidResult.failure(
            errorMessage: msg ?? '评标提交失败',
          );
        }
      } else {
        debugPrint('❌ 服务器响应格式错误');
        return ExpertBidResult.failure(
          errorMessage: '服务器响应格式错误',
        );
      }
    } catch (e) {
      debugPrint('❌ 专家评标提交异常: $e');
      return ExpertBidResult.failure(
        errorMessage: e.toString().replaceAll('Exception: ', ''),
      );
    }
  }

  /// 获取项目文件列表API
  /// 
  /// [projectId] 项目ID
  /// [supplierId] 供应商ID（文件类型为1或2时，供应商ID>0，否则此字段=0）
  /// [fileType] 文件类别（用于筛选）：0-项目方上传采购文件，1-供应商上传投标文件，2-供应商上传的合同，
  ///           3-项目实施过程文档，4-项目附件，5-终审文件，6-终验文件（验收归档资料）
  /// 
  /// ⚠️ 注意：返回的文件对象中也有一个 fileType 字段，表示文件的具体类型：
  ///   1-立项申请与批复资料
  ///   2-招标文件
  ///   3-中标的投标文件（正本）
  ///   4-中标通知书
  ///   5-合同文件
  ///   6-签收单
  ///   7-项目验收申请表
  ///   8-项目验收初验表
  ///   9-项目终验检查表
  ///   0-额外资料
  /// 
  /// 使用DioService自动携带的token进行请求
  /// 直接返回文件列表 List<SupplierFileModel>
  static Future<List<SupplierFileModel>> getProjectFiles({
    required int projectId,
    required int supplierId,
    required int fileType,
  }) async {
    try {
      debugPrint('📁 开始获取项目文件列表');
      debugPrint('📁 项目ID: $projectId, 供应商ID: $supplierId, 文件类型: $fileType');
      
      // 构建查询参数
      final queryParams = {
        'projectId': projectId.toString(),
        'supplierId': supplierId.toString(),
        'fileType': fileType.toString(),
      };
      
      debugPrint('📁 发送GET请求到: $projectFilesPath');
      debugPrint('📁 查询参数: $queryParams');
      
      // 使用DioService发送GET请求，token会被自动添加到请求头
      final response = await _dioService.get(
        projectFilesPath,
        queryParameters: queryParams,
      );
      
      debugPrint('📁 项目文件列表请求完成，状态码: ${response.statusCode}');
      
      // 解析响应数据
      if (response.data != null && response.data is Map<String, dynamic>) {
        final responseData = response.data as Map<String, dynamic>;
        
        debugPrint('📁 项目文件列表响应数据类型: ${responseData.runtimeType}');
        
        // 检查响应状态码
        final code = responseData['code']?.toInt() ?? -1;
        final msg = responseData['message']?.toString() ?? responseData['msg']?.toString();
        
        if (code == 0) { // 项目文件列表API成功时code为0
          // 成功响应 - 解析data字段为List<SupplierFileModel>
          final data = responseData['data'];
          if (data != null && data is List) {
            final fileList = data
                .map((item) {
                  if (item is Map<String, dynamic>) {
                    return SupplierFileModel.fromJson(item);
                  } else {
                    debugPrint('⚠️ 跳过无效的文件数据: $item');
                    return null;
                  }
                })
                .where((file) => file != null)
                .cast<SupplierFileModel>()
                .toList();
            
            debugPrint('✅ 获取项目文件列表成功，共 ${fileList.length} 个文件');
            
            // 打印文件信息摘要（仅在debug模式下）
            if (fileList.isNotEmpty) {
              for (final file in fileList) {
                debugPrint('📄 文件: ${file.fileName} (${file.fileTypeDescription}) - ${file.fileSizeReadable}');
              }
            }
            
            return fileList;
          } else if (data == null) {
            // 如果data为null，返回空列表
            debugPrint('📁 项目文件列表为空');
            return <SupplierFileModel>[];
          } else {
            debugPrint('❌ 项目文件列表数据格式错误: ${data.runtimeType}');
            throw Exception('项目文件列表数据格式错误');
          }
        } else {
          // 业务失败响应
          debugPrint('❌ 获取项目文件列表失败: $msg');
          throw Exception(msg ?? '获取项目文件列表失败');
        }
      } else {
        debugPrint('❌ 服务器响应格式错误');
        throw Exception('服务器响应格式错误');
      }
    } catch (e) {
      debugPrint('❌ 获取项目文件列表异常: $e');
      rethrow;
    }
  }
}
